package com.zhangmeng.windowportbind.utils;

import com.zhangmeng.windowportbind.dto.PortBind;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class PortUtils {

    public static List<PortBind> getUsedPorts() {
        List<PortBind> ports = new ArrayList<>();
        try {
            String command = isWindows() ? "netstat -ano -p tcp" : "netstat -tuln";

            Process process = Runtime.getRuntime().exec(command);
            try (BufferedReader reader = new BufferedReader(
                    new InputStreamReader(process.getInputStream()))) {

                String line;
                while ((line = reader.readLine()) != null) {
                    if (line.contains("LISTEN")) {
                        Matcher matcher = Pattern.compile("^\\s*(\\w+)\\s+([\\d.]+:\\d+)\\s+([\\d.]+:[\\d*]+)\\s+(\\w+)\\s+(\\d+)\\s*$").matcher(line);

                        //协议  本地地址          外部地址        状态           PID
                        //tcp  0.0.0.0:8080        0.0.0.0:*         LISTENING       12345
                        if (matcher.find()) {
                            String protocol = matcher.group(1);
                            String local_addr = matcher.group(2);
                            String remote_addr = matcher.group(3);
                            String state = matcher.group(4);
                            String pid = matcher.group(5);

                            PortBind portBind = new PortBind();
                            portBind.setProtocol(protocol);
                            portBind.setLocalIp(local_addr.split(":")[0]);
                            portBind.setLocalPort(Integer.parseInt(local_addr.split(":")[1]));
                            portBind.setRemoteIp(remote_addr.split(":")[0]);
                            portBind.setRemotePort(Integer.parseInt(remote_addr.split(":")[1]));
                            portBind.setState(state);
                            portBind.setPid(pid);

                            ports.add(portBind);
                        }
                    }
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return ports;
    }

    public static List<PortBind> getQueryPort(int port) {
        List<PortBind> usedPorts = getUsedPorts();
        List<PortBind> result = new ArrayList<>();
        for (PortBind portBind : usedPorts) {
            if (portBind.getLocalPort() == port) {
                result.add(portBind);
            }
        }
        return result;
    }

    private static boolean isWindows() {
        return System.getProperty("os.name").toLowerCase().contains("win");
    }

    public static boolean killProcessByPID(int pid) {
        try {
            // 使用 taskkill 命令并指定 /PID 参数来终止指定 PID 的进程
            Process proc = new ProcessBuilder("taskkill", "/F", "/PID", String.valueOf(pid)).start();
            // 等待命令执行完成
            int exitCode = proc.waitFor();
            if (exitCode == 0) {
                return true;
            } else {
                return false;
            }
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }
        return false;
    }
}
